#-------------------------------------------------------------------------------
# Name:        CropDetcShortCircuit
# Purpose:
#
# Author:      Daiyusi
#
# Created:     14/07/2021
# Copyright:   (c) asus 2021
# Licence:     <your licence>
#-------------------------------------------------------------------------------

import numpy as np
import os
from PIL import Image,ImageFont,ImageDraw
import matplotlib.pyplot as plt

def avg_sum(im):
    # 面均值
    s = np.float(0)
    h,w = im.shape
    for i in range(h):
        for j in range(w):
            s = s*((i*w+j)/(i*w+j+1)) + im[i,j]/(i*w+j+1)
    return s

def max_avg_sum(im):
    # 线均值最大值
    h,w = im.shape
    maxs = 0
    for i in range(w):
        s = np.float(0)
        for j in range(h):
            s =  s*(j/(j+1))+im[j,i]/(j+1)
        if s > maxs:
            maxs = s
    return maxs

def max2_avg_sum(im):
    # 半线均值最大值
    h,w = im.shape
    h2 = int(h/2)
    maxs1 = max_avg_sum(im[0:h2,0:])
    maxs2 = max_avg_sum(im[h2:,0:])

    if maxs1 > maxs2:
        return maxs1
    else:
        return maxs2
    '''
    s = (maxs1+maxs2)/2
    return s
    '''

def max3_avg_sum(im):
    # (半)线均值最大值与面均值的加权平均
    s = np.float(0)
    s0 = avg_sum(im)
    s1 = max_avg_sum(im)
    s2 = max2_avg_sum(im)
    s = 0.7*s2 + 0.3*s0
    return s

def uncovSearch(avgT,meanT):
    # 头尾板搜索计数,以p倍meanT为界
    n = [0,0] #[头,尾]
    p = 1.25

    for i in avgT:
        if i > p*meanT:
            n[0] = n[0]+1
        else:
            break

    for i in avgT[::-1]:
        if i > p*meanT:
            n[1] = n[1]+1
        else:
            break

    print('n:',n)
    return n

def stdDetect(im,num):
    # 单槽板极短路检测,在有盖布时忽略前后端n个板极
    diag = [0 for i in range(num)]
    avgT = [0 for i in range(num)]
    h,w = im.shape
    #print(h,w)
    stp = w/num

    for i in range(num):
        p1 = int(i*stp)
        p2 = int((i+1)*stp)
        subim = im[0:,p1:p2]
        avgT[i] = max3_avg_sum(subim)
        # print('avgT[',str(i+1),']:',avgT[i])

    meanT = np.mean(avgT)
    stdT = np.std(avgT)
#    print('meanT1:',meanT)

    difT = avgT-meanT
    uncov = [1 for i in range(num)]
    n=[0,0]
    '''
    uncov = [1 for i in range(num)] # 有多层盖布处标记0
    num_uncov = num
    sum_uncov = 0
    for i in range(num):
        if difT[i] < -20:
            num_uncov = num_uncov-1
            uncov[i] = 0
        sum_uncov = sum_uncov + uncov[i]*avgT[i]

    meanT = sum_uncov/num_uncov
    print('meanT:',meanT)
    # 前后端n个板极忽略，不纳入均值计算
    n=[0,0]
    if meanT < 155:
        #n = [3,3]
        n = uncovSearch(avgT,meanT)
        for i in range(-n[1],n[0]):
            if uncov[i] == 1:
                #uncov[i] = 0
                num_uncov = num_uncov-1
                sum_uncov = sum_uncov-avgT[i]
        meanT = sum_uncov/num_uncov

    difT = avgT-meanT

    # 忽略前后n个板极，以及多层盖布后求标准差
    avgT_normal=[]
    for i in range(n[0],num-n[1]):
        if uncov[i] == 1:
            avgT_normal.append(avgT[i])
    stdT = np.std(avgT_normal)
    #stdT = 7

    print('meanT2:',meanT)
    print('stdT:',stdT)
    print('avgT:',avgT)
    print('difT:',difT)
    '''

    print('meanT:', meanT)
    print('stdT:', stdT)
    # print('avgT:',avgT)
    print('difT:', np.round(difT, 1))

    k3,k2,k1=[4,2,1.7]
    # 标准差过小
    '''
    if stdT < 0.1*meanT:
        k3,k2,k1=[5,3,2]
    '''
    for i in range(n[0],num-n[1]):
        if uncov[i] == 1:
            if difT[i] > k3*stdT:
                diag[i] = 3
            elif difT[i] > k2*stdT:
                diag[i] = 2
            elif difT[i] > k1*stdT:
                diag[i] = 1

    # 对最前、后n块板极中未被多层盖布遮挡的板极单独做阈值检测
    th = [160,170,180]
    #th = [135,145,160] # 两端板极检测阈值
    for i in range(-n[1],n[0]):
        if uncov[i] == 1:
            if avgT[i] > th[2]:
                diag[i] = 3
            elif avgT[i] > th[1]:
                diag[i] = 2
            elif avgT[i] > th[0]:
                diag[i] = 1

    return diag


def DistorRemove(im,k1,k2):
    # 桶形畸变矫正
    s = im.shape
    img = np.zeros(s)
    img = np.uint8(img)

    for l1 in range(s[0]):
        y = l1-s[0]/2

        for l2 in range(s[1]):
            x = l2-s[1]/2
            x1 = np.round(x*(1+k1*x*x+k2*y*y))
            y1 = np.round(y*(1+k1*x*x+k2*y*y))
            x1 = np.int(x1+s[1]/2)
            y1 = np.int(y1+s[0]/2)

            # 超出边界部分强制为0
            if x1<0 and x1>=s[1] and y1<0 and y1>=s[0]:
                img[l1,l2] = 0;
            else:
                img[l1,l2] = im[y1,x1]
    return img

def CropOfBars(im):
    # 单槽自动裁剪（待完善）
    pass

def DecInit(num1,num2,num3):
    # 生成key为‘槽号-板极号’，值为0的初始化字典
    diag={}
    for i in range(num1[0],num1[1]+1):
        for j in range(num2[0],num2[1]+1):
            key=str(i)+'-'+str(j)
            diag[key]=[0 for i in range(num3)];
    return diag


def ShortCircuitDetect(im,num3=38,num2=[1,12],num1=[1,2]):
    # 短路检测主程序
    im = im.convert('L') # 转灰度图
    im = np.array(im) # 图片转数组形式存储

    # 生成初始化字典,全0
    diag = DecInit(num1,num2,num3)

    # 桶形畸变矫正
    k1=-3e-7;
    k2=-4e-7;
    img = DistorRemove(im,k1,k2)
    # plt.imshow(img,cmap='gray',interpolation='bicubic')
    # plt.show()

    # 手动定位裁剪
    p = [513,942,4,465] # 整槽1、2的上下纵坐标位置
    #q = [[[21,14,95,370],[116,19,194,380],[214,20,300,389],[321,27,413,398],[429,27,519,409],[548,24,637,406],[668,34,755,418],[779,35,864,411],[899,30,967,405],[1010,32,1069,412],[1106,35,1170,406],[1205,32,1264,400]],[[13,32,114,416],[117,35,205,415],[223,26,310,416],[331,25,422,418],[447,24,543,419],[559,25,657,424],[679,26,777,425],[796,29,884,426],[905,36,1000,433],[1014,42,1099,436],[1120,53,1199,439],[1229,56,1277,444]],]
    q = [[[10,13,101,370],[116,16,192,377],[216,18,295,388],[321,22,414,395],[430,24,522,404],[550,27,641,408],[664,30,754,411],[784,32,853,410],[902,34,970,413],[1010,35,1070,405],[1109,43,1172,402],[1202,37,1267,402]], [[3,33,113,418],[119,28,213,416],[226,29,311,416],[332,26,423,418],[447,24,542,419],[561,26,661,422],[676,27,775,425],[802,34,886,428],[908,39,998,431],[1017,47,1098,435],[1123,56,1197,440],[1229,56,1279,444]]]
    # 所有单槽中的板极短路检测
    for i in range(num1[1]-num1[0]+1):
        # 上、下整槽分离
        imBars = img[(p[2*i]-1):p[2*i+1],0:]
        # 单槽分离及其板极短路检测
        for j in range(num2[1]-num2[0]+1):
            im1bar = imBars[(q[i][j][1]-1):q[i][j][3],(q[i][j][0]-1):q[i][j][2]]
            #im1bar = np.resize(im1bar,[num3*10,100])
            #plt.imshow(im1bar,cmap='gray',interpolation='bicubic')
            #plt.show()
            diagBars = stdDetect(im1bar.T,num3) # 输入图片中板极纵向排列，0:正常 1:轻度 2:中度 3:重度
            key = str(i+1)+'-'+str(j+1)
            diag[key]=diagBars


            plt.figure()
            plt.subplot(2,1,1)
            plt.imshow(im1bar.T, interpolation='bicubic')
            plt.subplot(2,1,2)
            plt.axis([1,num3,0,3])
            plt.plot(list(range(1,num3+1)),diagBars,marker='*')
            plt.savefig('SDC00_'+str(i+1)+'-'+str(j+1)+'.jpg',dpi=120)
            # plt.show()

    return diag



def main():
    '''
    filePath = 'E:\\MatlabCode\\ElecBarCrop_20210707\\JiangXi\\Images\\'
    imList = os.listdir(filePath)
#    print(imList)
    k=0
    #l=len(imList)
    #imPath = 'E:\\MatlabCode\\ElecBarCrop_20210707\\JiangXi\\ImTest.jpg'
    imPath = filePath+imList[k]
    '''

    # 'E:\\PythonProject\\SCD\\Images\\capture20210716_082701.jpg'
    imPath = r'C:\RealPlayDemo\Snap\capture20210721_111115.jpg' #'E:\\PythonProject\\ShortCircuitDetection\\Test003.jpg'
    num1 = [1,2] # 起始-结束整槽号
    num2 = [1,12] # 起始-结束单槽号
    num3 = 38 # number of plates in one electrobath
    #print(imPath)
    img = Image.open(imPath) # read the image ( PIL image )
    diag=ShortCircuitDetect(img,num3,num2,num1) #短路检测
    print(diag)
    pass

if __name__ == '__main__':
    main()
